﻿#region

using System;
using System.Collections.Generic;
using System.Linq;
using HouseHoldBudget.Core.Data;
using HouseHoldBudget.Core.Entities.Budgets;
using HouseHoldBudget.Core.Entities.User;

#endregion

namespace HouseHoldBudget.Services.Budgets
{
    public class BudgetService : IBudgetService
    {
        #region Readonly & Static Fields

        private readonly IRepository<Budget> _budgetRepository;

        #endregion

        #region Constructors

        /// <summary>
        ///   Initializes a new instance of the <see cref="BudgetService" /> class.
        /// </summary>
        /// <param name="budgetRepository"> The budget repository. </param>
        public BudgetService(IRepository<Budget> budgetRepository)
        {
            _budgetRepository = budgetRepository;
        }

        #endregion

        #region IBudgetService Members

        /// <summary>
        ///   Gets my budgets list.
        /// </summary>
        /// <param name="budgetOwnerId"> The budget owner id. </param>
        /// <returns> </returns>
        public List<Budget> GetMyBudgets(Guid budgetOwnerId)
        {
            var query = from b in _budgetRepository.Table
                        where b.BudgetOwner.Id == budgetOwnerId
                        orderby b.BudgetName
                        select b;

            return query.ToList();
        }

        /// <summary>
        /// Gets all budgets.
        /// </summary>
        /// <param name="budgetUserId">The budget user id.</param>
        /// <returns></returns>
        public List<Budget> GetAllBudgets(Guid budgetUserId)
        {
            var query = _budgetRepository.Table;

            //all budgets where i'm actor
            List<Budget> budgetWhereActors = query.Where(p => p.BudgetActors.Any(a => a.Id == budgetUserId)).ToList();

            //all budget where i'm owner
            List<Budget> budgetWhereOwner = query.Where(p => p.BudgetOwner.Id == budgetUserId).ToList();

            budgetWhereActors.AddRange(budgetWhereOwner);
            return budgetWhereActors.OrderBy(p=>p.BudgetName).ToList();
        }

        /// <summary>
        /// Gets the budget actor.
        /// </summary>
        /// <param name="budgetId">The budget id.</param>
        /// <param name="userId">The user id.</param>
        /// <returns></returns>
        public BudgetUser GetBudgetActor(Guid budgetId, Guid userId)
        {
            var budget = GetBudgetById(budgetId);
            return budget.BudgetActors.SingleOrDefault(u => u.Id == userId);
        }

        /// <summary>
        ///   Inserts a budget.
        /// </summary>
        /// <param name="budget"> The budget. </param>
        public void InsertBudget(Budget budget)
        {
            _budgetRepository.Insert(budget);
        }

        /// <summary>
        ///   Gets a budget by id.
        /// </summary>
        /// <param name="budgetId"> The budget id. </param>
        /// <returns> </returns>
        public Budget GetBudgetById(Guid budgetId)
        {
            return _budgetRepository.GetById(budgetId);
        }

        /// <summary>
        /// Gets the budget actors.
        /// </summary>
        /// <param name="budgetId">The budget id.</param>
        /// <returns></returns>
        public List<BudgetUser> GetBudgetActors(Guid budgetId)
        {
            var budget = GetBudgetById(budgetId);
            return budget.BudgetActors.ToList();
        }

        /// <summary>
        ///   Updates the budget.
        /// </summary>
        /// <param name="budget"> The budget. </param>
        public void UpdateBudget(Budget budget)
        {
            _budgetRepository.Update(budget);
        }

        /// <summary>
        /// Deletes the budget.
        /// </summary>
        /// <param name="id">The id.</param>
        public void DeleteBudget(Guid id)
        {
            _budgetRepository.DeleteById(id);
        }

        #endregion
    }
}